package com.xx.doublexchat.common.chat.service.adapter;

import cn.hutool.core.bean.BeanUtil;
import com.xx.doublexchat.common.chat.domain.entity.Message;
import com.xx.doublexchat.common.chat.domain.entity.MessageMark;
import com.xx.doublexchat.common.chat.domain.enums.MessageMarkTypeEnum;
import com.xx.doublexchat.common.chat.domain.enums.MessageStatusEnum;
import com.xx.doublexchat.common.chat.domain.enums.MessageTypeEnum;
import com.xx.doublexchat.common.chat.domain.vo.request.ChatMessageRequest;
import com.xx.doublexchat.common.chat.domain.vo.request.msg.TextMsgRequest;
import com.xx.doublexchat.common.chat.domain.vo.response.ChatMessageResponse;
import com.xx.doublexchat.common.chat.service.strategy.msg.AbstractMsgHandler;
import com.xx.doublexchat.common.chat.service.strategy.msg.MsgHandlerFactory;
import com.xx.doublexchat.common.common.domain.enums.YesOrNoEnum;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

public class MessageAdapter {
    public static final Integer CAN_CALLBACK_GAP_COUNT = 100;

    /**
     * 组装消息保存信息
     *
     * @param request
     * @param uid
     * @return
     */
    public static Message buildMsgSave(ChatMessageRequest request, Long uid) {

        return Message.builder()
                .fromUid(uid)
                .roomId(request.getRoomId())
                .type(request.getMsgType())
                .status(MessageStatusEnum.NORMAL.getStatus())
                .build();

    }

    /**
     * 组装消息集合
     *
     * @param messages
     * @param msgMark
     * @param receiveUid
     * @return
     */
    public static List<ChatMessageResponse> buildMsgResp(List<Message> messages,
                                                         List<MessageMark> msgMark, Long receiveUid) {
        Map<Long, List<MessageMark>> markMap = msgMark.stream().collect(Collectors.groupingBy(MessageMark::getMsgId));
        return messages.stream().map(a -> {
                    ChatMessageResponse resp = new ChatMessageResponse();
                    //插入发送者信息
                    resp.setFromUser(buildFromUser(a.getFromUid()));
                    //插入消息信息
                    resp.setMessage(buildMessage(a, markMap.getOrDefault(a.getId(), new ArrayList<>()), receiveUid));
                    return resp;
                }).sorted(Comparator.comparing(a -> a.getMessage().getSendTime()))//帮前端排好序，更方便它展示
                .collect(Collectors.toList());
    }

    /**
     * 组装发送消息信息
     *
     * @param message
     * @param messageMarks
     * @param receiveUid
     * @return
     */
    private static ChatMessageResponse.Message buildMessage(Message message, List<MessageMark> messageMarks, Long receiveUid) {
        ChatMessageResponse.Message messageVO = new ChatMessageResponse.Message();
        BeanUtil.copyProperties(message, messageVO);
        messageVO.setSendTime(message.getCreateTime());
        //获取消息策略----确定是什么消息
        AbstractMsgHandler<?> msgHandler = MsgHandlerFactory.getStrategyNoNull(message.getType());
        if (Objects.nonNull(msgHandler)) {
            //插入主体消息
            messageVO.setBody(msgHandler.showMsg(message));
        }
        //消息标记表信息组合
        messageVO.setMessageMark(buildMsgMark(messageMarks, receiveUid));
        return messageVO;
    }

    /**
     * 组装消息标记表信息
     *
     * @param messageMarks
     * @param receiveUid
     * @return
     */
    private static ChatMessageResponse.MessageMark buildMsgMark(List<MessageMark> messageMarks, Long receiveUid) {
        //根据类型分类
        Map<Integer, List<MessageMark>> typeMap = messageMarks.stream().collect(Collectors.groupingBy(MessageMark::getType));
        //获取点赞集合
        List<MessageMark> likeMarks = typeMap.getOrDefault(MessageMarkTypeEnum.LIKE.getType(), new ArrayList<>());
        //获取被踩集合
        List<MessageMark> dislikeMarks = typeMap.getOrDefault(MessageMarkTypeEnum.DISLIKE.getType(), new ArrayList<>());
        ChatMessageResponse.MessageMark mark = new ChatMessageResponse.MessageMark();
        mark.setLikeCount(likeMarks.size());
        //设置该用户是否点赞
        mark.setUserLike(Optional.ofNullable(receiveUid).filter(uid ->
                        likeMarks.stream().anyMatch(a -> Objects.equals(a.getUid(), uid)))
                .map(a -> YesOrNoEnum.YES.getStatus()).orElse(YesOrNoEnum.NO.getStatus()));
        mark.setDislikeCount(dislikeMarks.size());
        //设置该用户是否举报
        mark.setUserDislike(Optional.ofNullable(receiveUid).filter(uid ->
                        dislikeMarks.stream().anyMatch(a -> Objects.equals(a.getUid(), uid)))
                .map(a -> YesOrNoEnum.YES.getStatus()).orElse(YesOrNoEnum.NO.getStatus()));
        return mark;
    }

    /**
     * 组装发送者信息
     *
     * @param fromUid
     * @return
     */
    private static ChatMessageResponse.UserInfo buildFromUser(Long fromUid) {
        ChatMessageResponse.UserInfo userInfo = new ChatMessageResponse.UserInfo();
        userInfo.setUid(fromUid);
        return userInfo;
    }

    /**
     * 组装同意好友信息
     *
     * @param roomId
     * @return
     */
    public static ChatMessageRequest buildAgreeMsg(Long roomId) {
        ChatMessageRequest chatMessageReq = new ChatMessageRequest();
        chatMessageReq.setRoomId(roomId);
        chatMessageReq.setMsgType(MessageTypeEnum.TEXT.getType());
        TextMsgRequest textMsgReq = new TextMsgRequest();
        textMsgReq.setContent("我们已经成为好友了，开始聊天吧");
        chatMessageReq.setBody(textMsgReq);
        return chatMessageReq;
    }
}
